#include "MyStructures.h"
#include <sstream>

#pragma region POINT

bool Point::operator == (const Point& p) const
{
	return x == p.x && y == p.y;
}

bool Point::operator != (const Point& p) const
{
	return !(*this == p);
}

Point& Point::operator = (const Point& p)
{
	x = p.x;
	y = p.y;
	return *this;
}

bool Point::operator < (const Point& p) const
{
	return x == p.x ? y < p.y : x < p.x;
}

bool Point::operator <= (const Point& p) const
{
	return *this == p || *this < p;
}

string Point::ToString () const
{
	stringstream ss;
	ss << "(" << x << "," << y << ") ";
	return ss.str ();
}

#pragma endregion POINT

#pragma region TARGET

Target::Target (const Point& Location, int moveIdx, TargetSubtype Subtype, TrooperType AuthorType, int LockedUntil, TrooperType LockedBy)
{
	location = Location;
	lastSeen = moveIdx;
	subtype = Subtype;
	authorType = AuthorType;
	lockedUntil = LockedUntil;
	lockedBy = LockedBy;

	switch (Subtype)
	{
	case TARGET_UNKNOWN_CELL:
		{
			type = TARGET_CELL;
			break;
		}
	case TARGET_BONUS_MEDKIT:
		{
			type = TARGET_BONUS;
			break;
		}
	case TARGET_BONUS_GRENADE:
		{
			type = TARGET_BONUS;
			break;
		}
	case TARGET_BONUS_RATION:
		{
			type = TARGET_BONUS;
			break;
		}
	case TARGET_JOINCALL_SUBTYPE:
		{
			type = TARGET_JOINCALL;
			break;
		}
	case TARGET_HELPCALL_SOLDIER:
		{
			type = TARGET_HELPCALL;
			break;
		}
	case TARGET_HELPCALL_COMMANDER:
		{
			type = TARGET_HELPCALL;
			break;
		}
	case TARGET_HELPCALL_MEDIC:
		{
			type = TARGET_HELPCALL;
			break;
		}
	default:
		{
			type = TARGET_ENEMY;
		}
	}
}

Target::Target (const Target& t)
{
	location = t.location;
	lastSeen = t.lastSeen;
	type = t.type;
	subtype = t.subtype;
	authorType = t.authorType;
	lockedUntil = t.lockedUntil;
	lockedBy = t.lockedBy;
}

bool Target::operator == (const Target& other) const
{
	return location == other.location &&
		subtype == other.subtype &&
		lastSeen == other.lastSeen;
}
bool Target::operator != (const Target& other) const
{
	return !(*this == other);
}

string Target::ToString () const
{
	stringstream ss;
	ss << "loc=(" << location.x << "," << location.y << ") "
		<< EnemySubtypeStrings[subtype]
	<< " seen=" << lastSeen
		<< " author=" << TrooperTypeStrings[authorType]
	<< " lockedUntil=" << lockedUntil
		<< " lockedBy=" << TrooperTypeStrings[lockedBy];

	return ss.str ();
}

#pragma endregion TARGET

string PresetAction::ToString ()
{
	stringstream ss;
	ss << "(" << actionTypeStrings[action] << ", " << x << ", " << y << ") ";
	return ss.str ();
}

string OneMoveDirective::ToString ()
{
	stringstream ss;
	ss << "moveIdx=" << moveIdx << ", next=" << next << " ";
	for (size_t i = 0; i < actions.size (); ++i)
	{
		ss << "(" << actionTypeStrings[actions[i].action] << ", " << actions[i].x << ", " << actions[i].y << ") ";
	}
	return ss.str ();
}

void OneMoveDirective::Clear ()
{
	actions.clear ();
	next = 0;
}

string BlockSignal::ToString ()
{
	stringstream ss;
	ss << "(author=" << TrooperTypeStrings[authorType] << ", assignee=" << TrooperTypeStrings[assigneeType] << ", blockedPath = ( ";
	for (size_t i = 0; i < blockedPath.size (); ++i)
	{
		ss << blockedPath[i].ToString ();
	}
	ss << ")";
	return ss.str ();
}

OneMoveDirective& OneMoveDirective::operator = (const OneMoveDirective& d)
{
	actions = d.actions;
	next = d.next;
	moveIdx = d.moveIdx;
	return *this;
}